/////////////////////////////////////////////////////
// File Name: frame_mux_tb.v
// Author: zeping fan
// mail:   zpfan007@163.com
// Created Time: 2023年06月26日 星期一 16时10分36秒
/////////////////////////////////////////////////////

module frame_mux_tb();

reg                             clk;
reg                             rst_n;
reg     [PORT_NUM-1:0]          mac_rx_state_fifo_empty;
reg     [PORT_NUM-1:0][15:0]    mac_rx_state_fifo_dout;
reg     [PORT_NUM-1:0][7:0]     mac_rx_data_fifo_dout;
reg                             frame_mux_state_fifo_rd;
reg                             frame_mux_data_fifo_rd;

wire    [PORT_NUM-1:0]          mac_rx_state_fifo_rd;
wire    [PORT_NUM-1:0]          mac_rx_data_fifo_rd;
wire    [15:0]                  frame_mux_state_fifo_dout;
wire                            frame_mux_state_fifo_empty;
wire    [7:0]                   frame_mux_data_fifo_dout;

parameter   PORT_NUM = 4;

always #5   clk = ~clk;

initial begin
    $fsdbDumpfile("frame_mux.fsdb");
    $fsdbDumpvars(0,frame_mux_tb);
    $fsdbDumpMDA();

    clk = 1'b0;
    rst_n = 1'b0;
    mac_rx_state_fifo_empty = {PORT_NUM{1'b0}};
    for(integer i=0;i<PORT_NUM;i=i+1)begin        
        mac_rx_state_fifo_dout[i] = 16'b0;
        mac_rx_data_fifo_dout[i]  = 16'b0;
    end
    frame_mux_state_fifo_rd = 1'b0;
    frame_mux_data_fifo_rd = 1'b0;
    
    repeat(2) @(posedge clk);#0;
    rst_n = 1'b1;
    
    repeat(2) @(posedge clk);#0;
    mac_rx_state_fifo_empty = 4'b1110;  //mac_rx0非空
    repeat(1)@(posedge clk);#0;
    mac_write(
                2'd0,        
                11'd60,
                48'hf0f1f2f3f4f5,
                48'he0e1e2e3e4e5,
                16'h0800,
                1'b0,
                1'b0
    );
    mac_rx_state_fifo_empty = 4'b1111;


    repeat(5) @(posedge clk);#0;
    mac_rx_state_fifo_empty = 4'b1101;  //mac_rx1非空
    repeat(1)@(posedge clk);#0;
    mac_write(
                2'd1,        
                11'd60,
                48'he0e1e2e3e4e5,
                48'hf0f1f2f3f4f5,
                16'h0800,
                1'b0,
                1'b0
    );
    mac_rx_state_fifo_empty = 4'b1111;

    repeat(5) @(posedge clk);#0;
    mac_rx_state_fifo_empty = 4'b1101;  //mac_rx1非空
    repeat(1)@(posedge clk);#0;
    mac_write(
                2'd1,        
                11'd60,
                48'he0e1e2e3e4e5,
                48'hf0f1f2f3f4f5,
                16'h0800,
                1'b1,
                1'b0
    );
    mac_rx_state_fifo_empty = 4'b1111;

    #200;
    $finish;
end





task mac_write;
    input   [1:0]   port;        
    input   [10:0]  frame_length;
    input   [47:0]  desti_addr;
    input   [47:0]  source_addr;
    input   [15:0]  frame_type;
    input           crc_err;
    input           length_err;
    integer         i;

    begin
    for(i=0;i<frame_length;i=i+1)begin
         @(posedge clk);#0;
        if(i==0)    mac_rx_data_fifo_dout[port] = desti_addr[47:40];
        else if(i==1)   mac_rx_data_fifo_dout[port] = desti_addr[39:32];
        else if(i==2)   mac_rx_data_fifo_dout[port] = desti_addr[31:24];
        else if(i==3)   mac_rx_data_fifo_dout[port] = desti_addr[23:16];
        else if(i==4)   mac_rx_data_fifo_dout[port] = desti_addr[15:8];
        else if(i==5)   mac_rx_data_fifo_dout[port] = desti_addr[7:0];
        else if(i==6)   mac_rx_data_fifo_dout[port] = source_addr[47:40];
        else if(i==7)   mac_rx_data_fifo_dout[port] = source_addr[39:32];
        else if(i==8)   mac_rx_data_fifo_dout[port] = source_addr[31:24];
        else if(i==9)   mac_rx_data_fifo_dout[port] = source_addr[23:16];
        else if(i==10)  mac_rx_data_fifo_dout[port] = source_addr[15:8];
        else if(i==11)  mac_rx_data_fifo_dout[port] = source_addr[7:0];
        else if(i==12)  mac_rx_data_fifo_dout[port] = frame_type[15:8];
        else if(i==13)  mac_rx_data_fifo_dout[port] = frame_type[7:0];
        else            mac_rx_data_fifo_dout[port] = i;
    end
    @(posedge clk);#0;
    mac_rx_state_fifo_dout[port] = {crc_err,length_err,3'b0,frame_length[10:0]};
    @(posedge clk);#0;
end
endtask
       





frame_mux #(
    .PORT_NUM(4)
)
x_frame_mux(
    .clk(clk),
    .rst_n(rst_n),
    .mac_rx_state_fifo_empty(mac_rx_state_fifo_empty),
    .mac_rx_state_fifo_rd(mac_rx_state_fifo_rd),
    .mac_rx_state_fifo_dout(mac_rx_state_fifo_dout),
    .mac_rx_data_fifo_rd(mac_rx_data_fifo_rd),
    .mac_rx_data_fifo_dout(mac_rx_data_fifo_dout),
    .frame_mux_state_fifo_empty(frame_mux_state_fifo_empty),
    .frame_mux_state_fifo_rd(frame_mux_state_fifo_rd),
    .frame_mux_state_fifo_dout(frame_mux_state_fifo_dout),
    .frame_mux_data_fifo_rd(frame_mux_data_fifo_rd),
    .frame_mux_data_fifo_dout(frame_mux_data_fifo_dout)
);

endmodule

